package com.fanfan.shiroadmin.modules.sys.auth;

import com.fanfan.shiroadmin.common.utils.HttpContextUtils;
import com.fanfan.shiroadmin.common.web.context.ResponseResultBody;
import com.google.gson.Gson;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.AuthenticatingFilter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * OAuth2 过滤器
 * @author DunFan.Liao
 * @date 2021/12/28 19:30
 */
@Component
public class SysAuthFilter extends AuthenticatingFilter
{
    @Value("${server.servlet.context-path}")
    private String contextPath;
    @Override
    protected AuthenticationToken createToken(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception
    {
        String token = getRequestToken((HttpServletRequest) servletRequest);
        if (StringUtils.isNotBlank(token))
        {
            return new SysAuthToken(token);
        }
        return null;
    }

    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)
    {
        if(((HttpServletRequest)request).getMethod().equals(RequestMethod.OPTIONS.name()))
        {
            Subject subject = getSubject(request, response);
            String permission = "";
            StringBuffer requestUrl = ((HttpServletRequest) request).getRequestURL();
            permission = StringUtils.isNotBlank(contextPath) ? requestUrl.substring(contextPath.length()) : requestUrl.toString();
            return subject.isPermitted(permission);
        }
        return false;
    }


    public static void main(String[] args) {
        StringBuffer requestURL = new StringBuffer("/api/sys/user/info");
        String contextPath = "/api/sys";
        System.out.println(requestURL.indexOf(contextPath));
        String substring = requestURL.substring(contextPath.length());
        System.out.println(substring);
    }

    @Override
    protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception
    {
       // 获取请求token,如果token不存在，直接返回401
        String token = getRequestToken((HttpServletRequest) servletRequest);
        if (StringUtils.isBlank(token))
        {
            HttpServletResponse response = (HttpServletResponse) servletResponse;
            response.setHeader("Access-Control-Allow-Credentials", "true");
            response.setHeader("Access-Control-Allow-Origin", HttpContextUtils.getOrigin());

            String json = new Gson().toJson(ResponseResultBody.createFailedResult("not available token"));
            response.getWriter().print(json);
            return false;
        }
        return executeLogin(servletRequest,servletResponse);
    }

    /**
     * 获取请求的token
     */
    private String getRequestToken(HttpServletRequest httpRequest)
    {
        //从header中获取token
        String token = httpRequest.getHeader("token");

        //如果header中不存在token，则从参数中获取token
        if(StringUtils.isBlank(token))
        {
            token = httpRequest.getParameter("token");
        }

        return token;
    }
}
